Trap Mechanism and Context Switch
Table of Contents
- Trap Table
- A table that stores the location of syscalls (aka trap handlers). Each syscall is assigned to a number, which is used by OS to tell the hardware what syscall to run. This trap table is set up by kernel at boot time, whose address is told to the hardware.
- User Mode, Kernel Mode
- User mode process can only run restricted operations, while kernel mode processes can run privileged operations.
- Trap, Return-From-Trap
- Trap and return-from-trap are special mechanisms for a user-mode process to run privileged operations.
1. Procedure Overview
The following tables include timer interrupt.
1.1. Boot-Time Preparation
| OS@boot(kernel mode) | Hardware | Program(user mode) |
|---|---|---|
| init trap table | ||
| remember addr of syscall & timer handler | ||
| start interrupt timer | ||
| start timer, interrupt CPU per X ms |
1.2. If the Trap is Caused by Syscall
| OS@run (kernel mode) | Hardware | Program (user mode) |
|---|---|---|
| Create entry for process list | ||
| Allocate memory for program | ||
| Load program from memory | ||
| Setup user stack with argv | ||
| Fill kernel stack with reg/PC | ||
| return-from-trap | ||
| restore regs (from kernel mode) | ||
| move to user mode | ||
jump to main() |
||
Run main() |
||
| call syscall | ||
| trap into OS | ||
| save regs (to kernel mode) | ||
| move to kernel mode | ||
| jump to trap handler | ||
| Handle trap | ||
| Execute syscall | ||
| return-from-trao | ||
| restore regs (from kernel stack) | ||
| move to user mode | ||
| jump to PC after trap | ||
return from main() |
||
trap via exit() |
||
| Free memory of process | ||
| Remove from process list |
1.3. If the Trap is Caused by Timer
| OS @ run (kernel mode) | Hardware | Program (user mode) |
|---|---|---|
| Process A | ||
| Timer interrupt | ||
| save regs(A) to kernel stack (A) | ||
| move to kernel mode | ||
| jump to trap handler | ||
| Handle the trap | ||
Call switch() routine: |
||
| save regs(A) to PCB(A) | ||
| restore regs(B) from PCB(B) | ||
| switch to kernel stack (B) | ||
| return from trap (into B) | ||
| restore regs(B) from kernel stack (B) | ||
| move to user mode | ||
| jumo to B’s Program Counter | ||
| Process B |
2. Explanation
Usually, programs are running in user mode. However, when it comes to privileged operations like file IO, such operations can only be done by OS, i.e., kernel mode. Such operations are called system call. System calls are APIs that are carefully exposed by OS.
So how can OS perform syscalls in kernel mode? Upon booting, OS stores a trap table into memory, and tells hardware about the memory address of the trap table.
If a program wants to perform some privileged operations, OS must trap from user mode into kernel mode to perform, and then return-from-trap back into user mode.
When executing the trap, in order to be able to return correctly, the hardware and OS should save enough of the caller’s registers. The hardware will push registers onto per-process kernel stack on trap; and pop these values from kernel stack on return-from-trap.
The next question, how to switch between processes? More specifically, how do CPU regain control?
- Cooperative Approach. CPU waits for syscalls from processes or illegal operations, so that after trapping into kernel mode, CPU can perform context switch to another process.
- Non-Cooperative Approach. CPU has a timer interrupt that when the interrupt is raised, the currently running process is halted and a pre-configured interrupt handler 1 in the OS runs.
During context switch, there are two types of register saves & restores
- When timer interrupt occurs, user registers are implicitly saved by hardware using the kernel stack of that process.
- When OS decides to switch from A to B, the kernel registers are explicitly saved by the software (OS) into memory (process structure).
Footnotes:
aka exception handler